﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RestSharp;
using WebApiDemo.Contract;
using Ymatou.ServiceCenter;
namespace Ymatou.ServiceCenter.UnitTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void DefaultGetTest()
        {
            //以同步请求的方式调用
            DefaultGetRequest request = new DefaultGetRequest();
            string result = ServiceClient.Execute(request,20000);//返回字符串
            Assert.IsNotNull(result);


            List<string> response = ServiceClient.Execute<DefaultGetRequest, List<string>>(request);//返回List
            Assert.IsNotNull(response);
            Assert.AreEqual(2,response.Count);

            string resultString =  RetryHelper.Retry<string>(() => ServiceClient.Execute(request, 20000),3, new TimeSpan(0, 0, 0, 10), () =>
            {
                //重试多次后还是失败，在这儿写自己的处理逻辑
            },"如果执行失败这儿给一个默认的返回值");
        }

        [TestMethod]
        public void DefaultGetTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default", Method.GET, ParameterBuildType.UrlQueryString);
            string result = ServiceClient.Execute(request, 20000);//返回字符串
            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void DefaultGetTaskAsyncTest()
        {
            //Net45下以异步Task的方式调用
            DefaultGetRequest request = new DefaultGetRequest();
            string result = ServiceClient.ExecuteTaskAsync(request).Result;
            Assert.IsNotNull(result);

            List<string> response = ServiceClient.ExecuteTaskAsync<DefaultGetRequest, List<string>>(request).Result;//返回List
            Assert.IsNotNull(response);
            Assert.AreEqual(2, response.Count);
        }

        [TestMethod]
        public void DefaultGetCallbackAsyncTest()
        {
            //通过异步回调的方式调用
            DefaultGetRequest request = new DefaultGetRequest();
            ServiceClient.ExecuteAsync(request, (response) =>
            {
                //在这个Action中对调用返回进行结果
                Console.WriteLine("DefaultGetCallbackAsyncTest:" + response);

            }, (ex) =>
            {
                //当调用、处理出现异常时，可以在这个Action中对异常进行记录或相应业务处理
                Console.WriteLine("DefaultGetCallbackAsyncTest:" + ex.ToString());
            });


            ServiceClient.ExecuteAsync<DefaultGetRequest, List<string>>(request, (response) =>
            {
                //在这个Action中对调用返回进行结果
                Console.WriteLine("DefaultGetCallbackAsyncTest:" + string.Join(",", response));

            }, (ex) =>
            {
                //当调用、处理出现异常时，可以在这个Action中对异常进行记录或相应业务处理
                Console.WriteLine("DefaultGetCallbackAsyncTest:" + ex.ToString());
            });
        }

        [TestMethod]
        public void DefaultGetTest2()
        {
            //TextResponse 为RPC客户端中自己带的一个接收纯字符串（不能json反序列化的字符串）的响应类
            DefaultGetRequest request = new DefaultGetRequest();
            TextResponse result = ServiceClient.Execute<DefaultGetRequest, TextResponse>(request);
            Assert.IsNotNull(result);
            Assert.IsNotNull(result.Result);
        }

        [TestMethod]
        public void DefaultGetIdTest()
        {
            DefaultGetIdRequest request = new DefaultGetIdRequest { Id = 100 };
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void DefaultGetIdTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/{id}", Method.GET, ParameterBuildType.UrlQueryString);
            request.AddParameter("id", "100");
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void DefaultPostTest()
        {
            DefaultPostRequest request = new DefaultPostRequest { Value = Guid.NewGuid().ToString() };
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
            Assert.AreNotEqual("", result);
        }

        [TestMethod]
        public void DefaultPostTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default", Method.POST,
                ParameterBuildType.FormUrlEncoded);
            request.AddParameter("", Guid.NewGuid().ToString());
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
            Assert.AreNotEqual("", result);
        }

        [TestMethod]
        public void DefaultPutTest()
        {
            DefaultPutRequest request = new DefaultPutRequest();
            IDictionary<string,string> headers = new Dictionary<string, string>();
            string orderId = Guid.NewGuid().ToString("N");
            headers.Add("OrderId", orderId);
            string result = ServiceClient.Execute(request,10000,headers);
            //Assert.AreEqual("\"put\"", result);
            Assert.AreEqual("\"" + orderId +"\"", result);
        }

        [TestMethod]
        public void DefaultPutTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default", Method.PUT, ParameterBuildType.UrlQueryString);
            IDictionary<string, string> headers = new Dictionary<string, string>();
            string orderId = Guid.NewGuid().ToString("N");
            headers.Add("OrderId", orderId);
            string result = ServiceClient.Execute(request, 10000, headers);
            //Assert.AreEqual("\"put\"", result);
            Assert.AreEqual("\"" + orderId + "\"", result);

            //DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default", Method.PUT, ParameterBuildType.UrlQueryString);
            //string result = ServiceClient.Execute(request);
            //Assert.AreEqual("\"put\"", result);
        }

        [TestMethod]
        public void DefaultPutIdTest()
        {
            DefaultPutIdRequest request = new DefaultPutIdRequest { Id = 100, Value = "ok" };
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
            string data = string.Format("\"Id:{0},Value:{1}\"", request.Id, request.Value);
            Assert.AreEqual(data, result);
        }

        [TestMethod]
        public void DefaultPutIdTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/{id}", Method.PUT,
                ParameterBuildType.QueryOrForm);
            request.AddParameter("id",100);
            request.AddParameter("","ok",ParameterType.GetOrPost);
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
            string data = string.Format("\"Id:{0},Value:{1}\"", 100, "ok");
            Assert.AreEqual(data, result);
        }




        [TestMethod]
        public void DefaultPutTaskAsyncTest()
        {
            DefaultPutIdRequest request = new DefaultPutIdRequest { Id = 100, Value = "ok" };
            string result =
                ServiceClient.ExecuteTaskAsync(ParameterBuildType.QueryOrForm, request, null, 10000, null).Result;
            Assert.IsNotNull(result);
            string data = string.Format("\"Id:{0},Value:{1}\"", request.Id, request.Value);
            Assert.AreEqual(data, result);
        }

        [TestMethod]
        public void DefaultPutTaskAsyncTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/{id}", Method.PUT,
                ParameterBuildType.QueryOrForm);
            request.AddParameter("id",100);
             request.AddParameter("","ok",ParameterType.GetOrPost);
          
            string result =
                ServiceClient.ExecuteTaskAsync(ParameterBuildType.QueryOrForm, request, null, 10000, null).Result;
            Assert.IsNotNull(result);
            string data = string.Format("\"Id:{0},Value:{1}\"", 100, "ok");
            Assert.AreEqual(data, result);
        }

        [TestMethod]
        public void DefaultDeleteTest()
        {
            DefaultDeleteRequest request = new DefaultDeleteRequest { Id = 100 };
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
            Assert.AreEqual("", result);
        }

        [TestMethod]
        public void DefaultDeleteTestByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/{id}", Method.DELETE,
                ParameterBuildType.UrlQueryString);
            request.AddParameter("id",100);
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
            Assert.AreEqual("", result);
        }

        [TestMethod]
        public void TestPostJson()
        {

            TestPostJsonRequest request = new TestPostJsonRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 3,
                Name = "tom",
                Price = 888M
            };

            TestPostJsonResponse response = ServiceClient.Execute<TestPostJsonRequest, TestPostJsonResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(request.Id, response.Id);
        }

        [TestMethod]
        public void TestPostJsonByDefaultRequest()
        {
            TestPostJsonRequest dto = new TestPostJsonRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 3,
                Name = "tom",
                Price = 888M
            };

            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/TestPostJson", Method.POST, ParameterBuildType.Json);
            request.AddParameter(dto);
            TestPostJsonResponse response = ServiceClient.Execute<DefaultRequest, TestPostJsonResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(dto.Id, response.Id);
        }

        [TestMethod]
        public void TestPost()
        {
            TestPostRequest request = new TestPostRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            TestPostResponse response = ServiceClient.Execute<TestPostRequest, TestPostResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(request.Id, response.Id);
        }

        [TestMethod]
        public void TestPostByDefaultRequest()
        {
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/TestPost", Method.POST, ParameterBuildType.UrlQueryString);
            string id = Guid.NewGuid().ToString("N");
            int age = 20;
            string name = "tom";
            decimal price = 888M;
            request.AddParameter("Id",id);
            request.AddParameter("Age",age);
            request.AddParameter("Name",name);
            request.AddParameter("Price",price);
            TestPostResponse response = ServiceClient.Execute<DefaultRequest, TestPostResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(id, response.Id);
        }


        [TestMethod]
        public void TestPostResult()
        {
            TestPostRequest request = new TestPostRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            //Result<TestPostResponse> result = ServiceClient.Execute<TestPostRequest, Result<TestPostResponse>>(request,
            //    (ex) => new Result<TestPostResponse>() { Message = ex.Message, StatusCode = -100 }, 10000, null, new ResourceAttribute("webapi.ymatou.com", "api/Default/TestPostResult", Method.POST, ParameterBuildType.FormUrlEncoded));

            //调用返回Result<T>类结构的接口，此种调用方法在出现异常时将不会在客户端中直接throw出异常。
            //如果服务端中对异常也做了Result<T>包装将会返回服务端的Result,如果服务端直接抛出了异常，或在调用时网络异常等，将会返一个事先指定好Result
            Result<TestPostResponse> result = ServiceClient.Execute<TestPostRequest, Result<TestPostResponse>>(request,
                (ex) => new Result<TestPostResponse>() { Message = ex.Message, StatusCode = -100 });//假定业务逻辑中规定-100表示系统异常
            Assert.IsNotNull(result);
            Assert.IsNotNull(result.Response);
            Assert.AreEqual(1, result.StatusCode);
        }


        [TestMethod]
        public void TestPostCallbackAsyncResult()
        {
            TestPostRequest request = new TestPostRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            ServiceClient.ExecuteAsync<TestPostRequest, Result<TestPostResponse>>(request, (result) =>
            {
                Console.WriteLine("TestPostCallbackAsyncResult:" + result.StatusCode);
            }, (ex) =>
            {
                Console.WriteLine("TestPostCallbackAsyncResult:" + ex);
            }, 10000, null, new ResourceAttribute("webapi.ymatou.com", "api/Default/TestPostResult", Method.POST, ParameterBuildType.FormUrlEncoded));
        }

        [TestMethod]
        public void TestPostTaskAsyncResult()
        {
            TestPostRequest request = new TestPostRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            Result<TestPostResponse> result = ServiceClient.ExecuteTaskAsync<TestPostRequest, Result<TestPostResponse>>(request,
                (ex) => new Result<TestPostResponse>() { Message = ex.Message, StatusCode = -100 }, 10000, null, new ResourceAttribute("webapi.ymatou.com", "api/Default/TestPostResult", Method.POST, ParameterBuildType.FormUrlEncoded)).Result;
            Assert.IsNotNull(result);
            Assert.IsNull(result.Response);
            Assert.AreEqual(-100, result.StatusCode);
        }

        [TestMethod]
        public void TestGet()
        {
            TestGetRequest request = new TestGetRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            TestGetResponse response = ServiceClient.Execute<TestGetRequest, TestGetResponse>("webapi.ymatou.com",request);
            Assert.IsNotNull(response);
            Assert.AreEqual(request.Id, response.Id);
        }

        [TestMethod]
        public void TestGetByDefaultRequest()
        {
            string id = Guid.NewGuid().ToString("N");
            int age = 20;
            string name = "tom";
            decimal price = 888M;
            DefaultRequest request = new DefaultRequest("webapi1.ymatou.com", "api/Default/TestGet", Method.GET,
                ParameterBuildType.UrlQueryString);
                        request.AddParameter("Id",id);
            request.AddParameter("Age",age);
            request.AddParameter("Name",name);
            request.AddParameter("Price",price);

            TestGetResponse response = ServiceClient.Execute<DefaultRequest, TestGetResponse>("webapi.ymatou.com", request);
            Assert.IsNotNull(response);
            Assert.AreEqual(id, response.Id);

        }

        [TestMethod]
        public void TestPut()
        {
            TestPutRequest request = new TestPutRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            TestPutResponse response = ServiceClient.Execute<TestPutRequest, TestPutResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(request.Id, response.Id);
        }


        [TestMethod]
        public void TestPutByDefaultRequest()
        {
            string id = Guid.NewGuid().ToString("N");
            int age = 20;
            string name = "tom";
            decimal price = 888M;
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/TestPut", Method.PUT, ParameterBuildType.UrlQueryString);
            request.AddParameter("Id", id);
            request.AddParameter("Age", age);
            request.AddParameter("Name", name);
            request.AddParameter("Price", price);
            TestPutResponse response = ServiceClient.Execute<DefaultRequest, TestPutResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(id, response.Id);
        }

        [TestMethod]
        public void TestDelete()
        {
            TestDeleteRequest request = new TestDeleteRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };

            TestDeleteResponse response = ServiceClient.Execute<TestDeleteRequest, TestDeleteResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(request.Id, response.Id);
        }

        [TestMethod]
        public void TestDeleteByDefaultRequest()
        {
            TestDeleteRequest dto = new TestDeleteRequest
            {
                Id = Guid.NewGuid().ToString("N"),
                Age = 20,
                Name = "tom",
                Price = 888M
            };
            DefaultRequest request = new DefaultRequest("webapi.ymatou.com", "api/Default/TestDelete", Method.DELETE, ParameterBuildType.Json);
            request.AddParameter(dto);
            TestDeleteResponse response = ServiceClient.Execute<DefaultRequest, TestDeleteResponse>(request);
            Assert.IsNotNull(response);
            Assert.AreEqual(dto.Id, response.Id);
        }

        [TestMethod]
        public void WebFormGetTest()
        {
            string id = Guid.NewGuid().ToString("N");
            WebFormGetTestRequest request = new WebFormGetTestRequest {Id = id};
            string result = ServiceClient.Execute(request);
            Assert.AreEqual(id,result);
        }

        [TestMethod]
        public void WebFormGetTest2()
        {
            //在某些特殊的业务场景下，站点的域名、接口等不一样，但是却在共用同一个dto的类库，
            //而每个dto类上只能打一个ResourceAttribute,这时如果想用这个dto去作为别的站点接口的数据协议包，
            //则需要在调用Execute方法时通过参数指定一个ResourceAttribute的实例
            string id = Guid.NewGuid().ToString("N");
            WebFormPostTestRequest request = new WebFormPostTestRequest { Id = id };
            string result = ServiceClient.Execute(request,10000,null,new ResourceAttribute("demo1.ymatou.com", "WebFormGetTest.aspx", Method.GET, ParameterBuildType.UrlQueryString));

            //如果Request类中的ResourceAttribute特性中的其他参数都一样，只是appId不一样，那么可以通过下面更简单的方式调用
            //string result = ServiceClient.Execute("demo2.ymatou.com",request);
            Assert.AreEqual(id, result);
        }

        [TestMethod]
        public void WebFormPostTest()
        {
            string id = Guid.NewGuid().ToString("N");
            WebFormPostTestRequest request = new WebFormPostTestRequest { Id = id };
            string result = ServiceClient.Execute(request);
            Assert.AreEqual(id, result);
        }

        [TestMethod]
        public void TestBaiduRequest()
        {
            BaiduRequest request = new BaiduRequest();
            string result = ServiceClient.Execute(request);
            Assert.IsNotNull(result);
        }

        //[TestMethod]
        //public void TestBaiduRequest2()
        //{
        //    Dictionary<string, string> paras = new Dictionary<string, string>
        //    {
        //        {"Id", "123"},
        //        {"Name", "tom"},
        //        {"Price", "456"},
        //        {"Age", "20"}
        //    };
        //    string result = ServiceClient.Execute(paras, null, null, new ResourceAttribute("webapi.ymatou.com", "api/Default/TestPost", Method.POST, ParameterBuildType.UrlQueryString));
        //    Assert.IsNotNull(result);
        //}
    }
}
